package clustering;
import java.io.*;
import java.util.*;
public class HAC_Clustering {
	private String PairwiseModel_file;
	private String Seed_Cluster_file;
	private String OneInstance_ID_file;
	private String Seed_Cluster_Similarity_file;
	private List<String> OneInstance_Ids;
	private ArrayList<ArrayList<Integer>> seed_clusters_index;
	public static void main(String args[]){
		new HAC_Clustering().Procedure(false);
		//new HAC_Clustering().Procedure(true);
	}
	public void Procedure(boolean python){
		ReadIdList(OneInstance_ID_file); // the one-instance pmid list file 
		if(!python){
			Cluster_Similarity_by_PairwiseModel similarity = new Cluster_Similarity_by_PairwiseModel(OneInstance_Ids.size());
			similarity.ReadPairwise_Model_Similarities(PairwiseModel_file); // the output from Main file,prediction_file from Main.
			similarity.ReadClusters(Seed_Cluster_file); // output from last step (python output file)
			similarity.Write_Cluster_Similarity(Seed_Cluster_Similarity_file);
		}
		
		/*After getting hac clusters index from the python code, we can get clusters with articles pmid*/
		else{
			ReadSeedClustersIndex(Seed_Cluster_file);
			Write_SeedCluster_PMIDs(""); // output, seed_cluster_pmid_file
			Write_HACCluster_PMIDs("","");//hac_cluster_python_file from last step (python output file), output: hac_cluster_pmid_file
		}
	}
	public void ReadIdList(String filename){
		OneInstance_Ids = new ArrayList<String>();
		File f = new File(filename);
		FileInputStream fis;
		try{
			fis = new FileInputStream(f);
			InputStreamReader isr=new InputStreamReader(fis);
			BufferedReader br=new BufferedReader(isr);
			String line = br.readLine();
			while(line != null){
				line = line.trim();
				if(line.length()>0){
					OneInstance_Ids.add(line);
				}
				line = br.readLine();
			}
			br.close();
		}catch(IOException e)
		{
			e.printStackTrace();
		}
	}
	
	public void ReadSeedClustersIndex(String filename){
		seed_clusters_index = new ArrayList<ArrayList<Integer>>();
		File f = new File(filename);
		FileInputStream fis;
		try{
			fis = new FileInputStream(f);
			InputStreamReader isr=new InputStreamReader(fis);
			BufferedReader br=new BufferedReader(isr);
			String line = br.readLine();
			while(line != null){
				line = line.trim();
				if(line.length()>0){
					String s[] = line.split(" ");
					ArrayList<Integer> cluster_index = new ArrayList<Integer>();
					for(int i=1; i<s.length; i++)
						cluster_index.add(Integer.valueOf(s[i]));
					seed_clusters_index.add(cluster_index);
				}
				line = br.readLine();
			}
			br.close();
		}catch(IOException e)
		{
			e.printStackTrace();
		}
	}
	
	public void Write_SeedCluster_PMIDs(String writefile){
		File f = new File(writefile);
		OutputStreamWriter write;
		try{
			write = new OutputStreamWriter(new FileOutputStream(f,false));
			BufferedWriter bw =new BufferedWriter(write);
			for(ArrayList<Integer> cluster: seed_clusters_index){
				bw.write(String.valueOf(cluster.size()));
				for(int id_index: cluster)
					bw.write("\t"+String.valueOf(OneInstance_Ids.get(id_index)));
				bw.newLine();
			}
				
			bw.close();
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	
	public void Write_HACCluster_PMIDs(String hac_cluster_index_file, String hac_cluster_PMID_file){
		File f = new File(hac_cluster_index_file);
		FileInputStream fis;
		File f1 = new File(hac_cluster_PMID_file);
		OutputStreamWriter write;
		try{
			fis = new FileInputStream(f);
			InputStreamReader isr=new InputStreamReader(fis);
			BufferedReader br=new BufferedReader(isr);
			write = new OutputStreamWriter(new FileOutputStream(f1,false));
			BufferedWriter bw =new BufferedWriter(write);
			String line = br.readLine();
			while(line != null){
				line = line.trim();
				String s[] = line.split(" ");
				int count = 0;
				for(int i=1; i<s.length; i++)		
					count += seed_clusters_index.get(Integer.valueOf(s[i])).size();
				bw.write(String.valueOf(count));
				for(int i=1; i<s.length; i++){
					for(int id_index: seed_clusters_index.get(Integer.valueOf(s[i])))
						bw.write("\t"+OneInstance_Ids.get(id_index));
				}
				bw.newLine();
				line = br.readLine();
			}
			br.close();
			bw.close();
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	
}
